package com.similarity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import sun.awt.SunToolkit.InfiniteLoop;

import com.model.DataModel;
import com.model.TagBasedUserDataModel;
import com.model.TagBasedDataModel;

public class TagSimilarity {
	private TagBasedDataModel datamodel;

	public TagSimilarity(DataModel datamodel) {
		this.datamodel = (TagBasedDataModel) datamodel;
	}

	public Double calculateSimilarity(Map<String, Integer> currentTagVector,
			Long imageID) {
		Double sim = 0.0d;
		Double upperPortion = 0.0d;
		Double lowerPortion = 0.0d;

		HashMap<String, Integer> imageTagVector = datamodel
				.getTagVectorbyImage(imageID);
		Double avgfreq = calculateAverageFrequency(imageTagVector);
		Iterator<String> iter = currentTagVector.keySet().iterator();
		while (iter.hasNext()) {
			String tmpTag = iter.next();
			if (imageTagVector.containsKey(tmpTag)) {
				upperPortion += currentTagVector.get(tmpTag)
						* imageTagVector.get(tmpTag);
				lowerPortion += Math.abs((imageTagVector.get(tmpTag) - avgfreq)
						* (imageTagVector.get(tmpTag) - avgfreq));
			}
		}
		sim = upperPortion / Math.sqrt(lowerPortion);
		if (upperPortion == 0)
			sim = 0.0;

		return sim;
	}

	public Double calculateTagVectorSimilarity(
			HashMap<String, Integer> currentTagVector,
			HashMap<String, Integer> RequesterTagVector) {

		Double sim = 0.0d;
		Double upperPortion = 0.0d;
		Double lowerPortion = 0.0d;
		Boolean hasCommonTags = false;

		Iterator<String> iterCheck = currentTagVector.keySet().iterator();
		while (iterCheck.hasNext()) {
			if (RequesterTagVector.containsKey(iterCheck.next())){
			hasCommonTags = true;
			break;
			}
		}

		if (!hasCommonTags)
			return 0.0;
		Double avgfreq = calculateAverageFrequency(RequesterTagVector);
		Iterator<String> iter = currentTagVector.keySet().iterator();
		while (iter.hasNext()) {
			String tmpTag = iter.next();
			if (RequesterTagVector.containsKey(tmpTag)) {
				upperPortion += currentTagVector.get(tmpTag)
						* RequesterTagVector.get(tmpTag);
				lowerPortion += Math
						.abs((RequesterTagVector.get(tmpTag) - avgfreq)
								* (RequesterTagVector.get(tmpTag) - avgfreq));
			}
		}
		if (lowerPortion == 0.0)
			lowerPortion = 1.0;
		sim = upperPortion / Math.sqrt(lowerPortion);
		if (upperPortion == 0)
			sim = 0.0;

		return sim;

	}

	// /////////////////////////////////
	public Double CalculateS_Similarity(
			HashMap<String, Integer> currentTagVector,
			HashMap<String, Integer> RequesterTagVector) {
		Double sim = 0.0;
		Boolean hasCommonTags = false;
		Double upperPortion = 0.0d;
		Double lowerPortion = 0.0d;

		Iterator<String> iterCheck = currentTagVector.keySet().iterator();
		while (iterCheck.hasNext()) {
			if (RequesterTagVector.containsKey(iterCheck.next())){
			hasCommonTags = true;
			break;
			}
		}

		if (!hasCommonTags)
			return 0.0;

		Iterator<String> iter = currentTagVector.keySet().iterator();
		while (iter.hasNext()) {
			String tmpTag = iter.next();
			if (RequesterTagVector.containsKey(tmpTag)) {
				upperPortion += RequesterTagVector.get(tmpTag)
						+ currentTagVector.get(tmpTag);

			}
		}
		lowerPortion += RequesterTagVector.size() + currentTagVector.size();
		if(lowerPortion==0)
			lowerPortion=0.0;
		sim = upperPortion / lowerPortion;
		
		return sim;
	}

	// //////////////////////////////////
	private Double calculateAverageFrequency(HashMap<String, Integer> vector) {
		Double avgFreq = 0.0d;
		Iterator<Integer> iter = vector.values().iterator();
		while (iter.hasNext()) {
			avgFreq += iter.next();
		}
		avgFreq = avgFreq / (vector.keySet().size());
		return avgFreq;
	}
}
